
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>django.test.client &#8212; Django 2.2.12.dev20200304094918 documentation</title>
    <link rel="stylesheet" href="../../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />



 
<script type="text/javascript" src="../../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../../../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../../index.html">Django 2.2.12.dev20200304094918 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../../index.html">Home</a>  |
        <a title="Table of contents" href="../../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../../genindex.html">Index</a>  |
        <a title="Module index" href="../../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="_modules-django-test-client">
            
  <h1>Source code for django.test.client</h1><div class="highlight"><pre>
<span></span><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">mimetypes</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">copy</span> <span class="k">import</span> <span class="n">copy</span>
<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">partial</span>
<span class="kn">from</span> <span class="nn">http</span> <span class="k">import</span> <span class="n">HTTPStatus</span>
<span class="kn">from</span> <span class="nn">importlib</span> <span class="k">import</span> <span class="n">import_module</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="k">import</span> <span class="n">BytesIO</span>
<span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="k">import</span> <span class="n">unquote_to_bytes</span><span class="p">,</span> <span class="n">urljoin</span><span class="p">,</span> <span class="n">urlparse</span><span class="p">,</span> <span class="n">urlsplit</span>

<span class="kn">from</span> <span class="nn">django.conf</span> <span class="k">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">django.core.handlers.base</span> <span class="k">import</span> <span class="n">BaseHandler</span>
<span class="kn">from</span> <span class="nn">django.core.handlers.wsgi</span> <span class="k">import</span> <span class="n">WSGIRequest</span>
<span class="kn">from</span> <span class="nn">django.core.serializers.json</span> <span class="k">import</span> <span class="n">DjangoJSONEncoder</span>
<span class="kn">from</span> <span class="nn">django.core.signals</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">got_request_exception</span><span class="p">,</span> <span class="n">request_finished</span><span class="p">,</span> <span class="n">request_started</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="k">import</span> <span class="n">close_old_connections</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="k">import</span> <span class="n">HttpRequest</span><span class="p">,</span> <span class="n">QueryDict</span><span class="p">,</span> <span class="n">SimpleCookie</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="k">import</span> <span class="n">TemplateDoesNotExist</span>
<span class="kn">from</span> <span class="nn">django.test</span> <span class="k">import</span> <span class="n">signals</span>
<span class="kn">from</span> <span class="nn">django.test.utils</span> <span class="k">import</span> <span class="n">ContextList</span>
<span class="kn">from</span> <span class="nn">django.urls</span> <span class="k">import</span> <span class="n">resolve</span>
<span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="k">import</span> <span class="n">force_bytes</span>
<span class="kn">from</span> <span class="nn">django.utils.functional</span> <span class="k">import</span> <span class="n">SimpleLazyObject</span>
<span class="kn">from</span> <span class="nn">django.utils.http</span> <span class="k">import</span> <span class="n">urlencode</span>
<span class="kn">from</span> <span class="nn">django.utils.itercompat</span> <span class="k">import</span> <span class="n">is_iterable</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;Client&#39;</span><span class="p">,</span> <span class="s1">&#39;RedirectCycleError&#39;</span><span class="p">,</span> <span class="s1">&#39;RequestFactory&#39;</span><span class="p">,</span> <span class="s1">&#39;encode_file&#39;</span><span class="p">,</span> <span class="s1">&#39;encode_multipart&#39;</span><span class="p">)</span>


<span class="n">BOUNDARY</span> <span class="o">=</span> <span class="s1">&#39;BoUnDaRyStRiNg&#39;</span>
<span class="n">MULTIPART_CONTENT</span> <span class="o">=</span> <span class="s1">&#39;multipart/form-data; boundary=</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">BOUNDARY</span>
<span class="n">CONTENT_TYPE_RE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;.*; charset=([\w\d-]+);?&#39;</span><span class="p">)</span>
<span class="c1"># Structured suffix spec: https://tools.ietf.org/html/rfc6838#section-4.2.8</span>
<span class="n">JSON_CONTENT_TYPE_RE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^application\/(.+\+)?json&#39;</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">RedirectCycleError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;The test client has been asked to follow a redirect loop.&quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">last_response</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">last_response</span> <span class="o">=</span> <span class="n">last_response</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">last_response</span><span class="o">.</span><span class="n">redirect_chain</span>


<span class="k">class</span> <span class="nc">FakePayload</span><span class="p">:</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A wrapper around BytesIO that restricts what can be read since data from</span>
<span class="sd">    the network can&#39;t be seeked and cannot be read outside of its content</span>
<span class="sd">    length. This makes sure that views can&#39;t do anything under the test client</span>
<span class="sd">    that wouldn&#39;t work in real life.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__content</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">if</span> <span class="n">content</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span>

    <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num_bytes</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="k">if</span> <span class="n">num_bytes</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">num_bytes</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="ow">or</span> <span class="mi">0</span>
        <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">&gt;=</span> <span class="n">num_bytes</span><span class="p">,</span> <span class="s2">&quot;Cannot read more than the available bytes from the HTTP incoming data.&quot;</span>
        <span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">num_bytes</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">-=</span> <span class="n">num_bytes</span>
        <span class="k">return</span> <span class="n">content</span>

    <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unable to write a payload after he&#39;s been read&quot;</span><span class="p">)</span>
        <span class="n">content</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">closing_iterator_wrapper</span><span class="p">(</span><span class="n">iterable</span><span class="p">,</span> <span class="n">close</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">yield from</span> <span class="n">iterable</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
        <span class="n">close</span><span class="p">()</span>                                 <span class="c1"># will fire request_finished</span>
        <span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">conditional_content_removal</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Simulate the behavior of most Web servers by removing the content of</span>
<span class="sd">    responses for HEAD requests, 1xx, 204, and 304 responses. Ensure</span>
<span class="sd">    compliance with RFC 7230, section 3.3.3.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="mi">100</span> <span class="o">&lt;=</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">&lt;</span> <span class="mi">200</span> <span class="ow">or</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">204</span><span class="p">,</span> <span class="mi">304</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
            <span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
    <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;HEAD&#39;</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
            <span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
    <span class="k">return</span> <span class="n">response</span>


<span class="k">class</span> <span class="nc">ClientHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A HTTP Handler that can be used for testing purposes. Use the WSGI</span>
<span class="sd">    interface to compose requests, but return the raw HttpResponse object with</span>
<span class="sd">    the originating WSGIRequest attached to its ``wsgi_request`` attribute.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span> <span class="o">=</span> <span class="n">enforce_csrf_checks</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">):</span>
        <span class="c1"># Set up middleware if needed. We couldn&#39;t do this earlier, because</span>
        <span class="c1"># settings weren&#39;t available.</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_middleware_chain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">load_middleware</span><span class="p">()</span>

        <span class="n">request_started</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
        <span class="n">request_started</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="n">environ</span><span class="o">=</span><span class="n">environ</span><span class="p">)</span>
        <span class="n">request_started</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
        <span class="n">request</span> <span class="o">=</span> <span class="n">WSGIRequest</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
        <span class="c1"># sneaky little hack so that we can easily get round</span>
        <span class="c1"># CsrfViewMiddleware.  This makes life easier, and is probably</span>
        <span class="c1"># required for backwards compatibility with external tests against</span>
        <span class="c1"># admin views.</span>
        <span class="n">request</span><span class="o">.</span><span class="n">_dont_enforce_csrf_checks</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span>

        <span class="c1"># Request goes through middleware.</span>
        <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_response</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>

        <span class="c1"># Simulate behaviors of most Web servers.</span>
        <span class="n">conditional_content_removal</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

        <span class="c1"># Attach the originating request to the response so that it could be</span>
        <span class="c1"># later retrieved.</span>
        <span class="n">response</span><span class="o">.</span><span class="n">wsgi_request</span> <span class="o">=</span> <span class="n">request</span>

        <span class="c1"># Emulate a WSGI server by calling the close method on completion.</span>
        <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
            <span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="n">closing_iterator_wrapper</span><span class="p">(</span>
                <span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
            <span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>                    <span class="c1"># will fire request_finished</span>
            <span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">response</span>


<span class="k">def</span> <span class="nf">store_rendered_templates</span><span class="p">(</span><span class="n">store</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Store templates and contexts that are rendered.</span>

<span class="sd">    The context is copied so that it is an accurate representation at the time</span>
<span class="sd">    of rendering.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">store</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
    <span class="k">if</span> <span class="s1">&#39;context&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">store</span><span class="p">:</span>
        <span class="n">store</span><span class="p">[</span><span class="s1">&#39;context&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ContextList</span><span class="p">()</span>
    <span class="n">store</span><span class="p">[</span><span class="s1">&#39;context&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">encode_multipart</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Encode multipart POST data from a dictionary of form values.</span>

<span class="sd">    The key will be used as the form data name; the value will be transmitted</span>
<span class="sd">    as content. If the value is a file, the contents of the file will be sent</span>
<span class="sd">    as an application/octet-stream; otherwise, str(value) will be sent.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">to_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>

    <span class="c1"># Not by any means perfect, but good enough for our purposes.</span>
    <span class="k">def</span> <span class="nf">is_file</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">callable</span><span class="p">(</span><span class="n">thing</span><span class="o">.</span><span class="n">read</span><span class="p">)</span>

    <span class="c1"># Each bit of the multipart form data could be either a form value or a</span>
    <span class="c1"># file, or a *list* of form values and/or files. Remember that HTTP field</span>
    <span class="c1"># names can be duplicated!</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
                <span class="s1">&#39;Cannot encode None as POST data. Did you mean to pass an &#39;</span>
                <span class="s1">&#39;empty string or omit the value?&#39;</span>
            <span class="p">)</span>
        <span class="k">elif</span> <span class="n">is_file</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
            <span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
        <span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">is_file</span><span class="p">(</span><span class="n">item</span><span class="p">):</span>
                    <span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">item</span><span class="p">))</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="p">[</span>
                        <span class="s1">&#39;--</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">,</span>
                        <span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">key</span><span class="p">,</span>
                        <span class="s1">&#39;&#39;</span><span class="p">,</span>
                        <span class="n">item</span>
                    <span class="p">])</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="p">[</span>
                <span class="s1">&#39;--</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">,</span>
                <span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">key</span><span class="p">,</span>
                <span class="s1">&#39;&#39;</span><span class="p">,</span>
                <span class="n">value</span>
            <span class="p">])</span>

    <span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span>
        <span class="n">to_bytes</span><span class="p">(</span><span class="s1">&#39;--</span><span class="si">%s</span><span class="s1">--&#39;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">),</span>
        <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
    <span class="p">])</span>
    <span class="k">return</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\r\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">to_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>

    <span class="c1"># file.name might not be a string. For example, it&#39;s an int for</span>
    <span class="c1"># tempfile.TemporaryFile().</span>
    <span class="n">file_has_string_name</span> <span class="o">=</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">if</span> <span class="n">file_has_string_name</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>

    <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;content_type&#39;</span><span class="p">):</span>
        <span class="n">content_type</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">content_type</span>
    <span class="k">elif</span> <span class="n">filename</span><span class="p">:</span>
        <span class="n">content_type</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">filename</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">content_type</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">if</span> <span class="n">content_type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">content_type</span> <span class="o">=</span> <span class="s1">&#39;application/octet-stream&#39;</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span> <span class="ow">or</span> <span class="n">key</span>
    <span class="k">return</span> <span class="p">[</span>
        <span class="n">to_bytes</span><span class="p">(</span><span class="s1">&#39;--</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">),</span>
        <span class="n">to_bytes</span><span class="p">(</span><span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;; filename=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span>
                 <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">filename</span><span class="p">)),</span>
        <span class="n">to_bytes</span><span class="p">(</span><span class="s1">&#39;Content-Type: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">content_type</span><span class="p">),</span>
        <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
        <span class="n">to_bytes</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
    <span class="p">]</span>


<div class="viewcode-block" id="RequestFactory"><a class="viewcode-back" href="../../../topics/testing/advanced.html#django.test.RequestFactory">[docs]</a><span class="k">class</span> <span class="nc">RequestFactory</span><span class="p">:</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Class that lets you create mock Request objects for use in testing.</span>

<span class="sd">    Usage:</span>

<span class="sd">    rf = RequestFactory()</span>
<span class="sd">    get_request = rf.get(&#39;/hello/&#39;)</span>
<span class="sd">    post_request = rf.post(&#39;/submit/&#39;, {&#39;foo&#39;: &#39;bar&#39;})</span>

<span class="sd">    Once you have a request object you can pass it to any view function,</span>
<span class="sd">    just as if that view had been hooked up using a URLconf.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">json_encoder</span><span class="o">=</span><span class="n">DjangoJSONEncoder</span><span class="p">,</span> <span class="o">**</span><span class="n">defaults</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">json_encoder</span> <span class="o">=</span> <span class="n">json_encoder</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="n">defaults</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">errors</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">_base_environ</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        The base environment for a request.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># This is a minimal valid WSGI environ dictionary, plus:</span>
        <span class="c1"># - HTTP_COOKIE: for cookie support,</span>
        <span class="c1"># - REMOTE_ADDR: often useful, see #8551.</span>
        <span class="c1"># See https://www.python.org/dev/peps/pep-3333/#environ-variables</span>
        <span class="k">return</span> <span class="p">{</span>
            <span class="s1">&#39;HTTP_COOKIE&#39;</span><span class="p">:</span> <span class="s1">&#39;; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span>
                <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">=</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">morsel</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">morsel</span><span class="o">.</span><span class="n">coded_value</span><span class="p">)</span>
                <span class="k">for</span> <span class="n">morsel</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
            <span class="p">)),</span>
            <span class="s1">&#39;PATH_INFO&#39;</span><span class="p">:</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span>
            <span class="s1">&#39;REMOTE_ADDR&#39;</span><span class="p">:</span> <span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span>
            <span class="s1">&#39;REQUEST_METHOD&#39;</span><span class="p">:</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
            <span class="s1">&#39;SCRIPT_NAME&#39;</span><span class="p">:</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
            <span class="s1">&#39;SERVER_NAME&#39;</span><span class="p">:</span> <span class="s1">&#39;testserver&#39;</span><span class="p">,</span>
            <span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">:</span> <span class="s1">&#39;80&#39;</span><span class="p">,</span>
            <span class="s1">&#39;SERVER_PROTOCOL&#39;</span><span class="p">:</span> <span class="s1">&#39;HTTP/1.1&#39;</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.version&#39;</span><span class="p">:</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
            <span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">:</span> <span class="s1">&#39;http&#39;</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.input&#39;</span><span class="p">:</span> <span class="n">FakePayload</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">),</span>
            <span class="s1">&#39;wsgi.errors&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">errors</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.multiprocess&#39;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.multithread&#39;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.run_once&#39;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
            <span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">,</span>
            <span class="o">**</span><span class="n">request</span><span class="p">,</span>
        <span class="p">}</span>

    <span class="k">def</span> <span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
        <span class="s2">&quot;Construct a generic request object.&quot;</span>
        <span class="k">return</span> <span class="n">WSGIRequest</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_base_environ</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">_encode_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">content_type</span> <span class="ow">is</span> <span class="n">MULTIPART_CONTENT</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">encode_multipart</span><span class="p">(</span><span class="n">BOUNDARY</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Encode the content so that the byte representation is correct.</span>
            <span class="n">match</span> <span class="o">=</span> <span class="n">CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content_type</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">match</span><span class="p">:</span>
                <span class="n">charset</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">charset</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span>
            <span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">charset</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_encode_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return encoded JSON if data is a dict, list, or tuple and content_type</span>
<span class="sd">        is application/json.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">should_encode</span> <span class="o">=</span> <span class="n">JSON_CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content_type</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">json_encoder</span><span class="p">)</span> <span class="k">if</span> <span class="n">should_encode</span> <span class="k">else</span> <span class="n">data</span>

    <span class="k">def</span> <span class="nf">_get_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parsed</span><span class="p">):</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">path</span>
        <span class="c1"># If there are parameters, add them</span>
        <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">params</span><span class="p">:</span>
            <span class="n">path</span> <span class="o">+=</span> <span class="s2">&quot;;&quot;</span> <span class="o">+</span> <span class="n">parsed</span><span class="o">.</span><span class="n">params</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">unquote_to_bytes</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="c1"># Replace the behavior where non-ASCII values in the WSGI environ are</span>
        <span class="c1"># arbitrarily decoded with ISO-8859-1.</span>
        <span class="c1"># Refs comment in `get_bytes_from_wsgi()`.</span>
        <span class="k">return</span> <span class="n">path</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;iso-8859-1&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a GET request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">data</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span>
            <span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">:</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
            <span class="o">**</span><span class="n">extra</span><span class="p">,</span>
        <span class="p">})</span>

    <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">MULTIPART_CONTENT</span><span class="p">,</span>
             <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a POST request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">({}</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
        <span class="n">post_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;POST&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">post_data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">,</span>
                            <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">head</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a HEAD request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">data</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;HEAD&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span>
            <span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">:</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
            <span class="o">**</span><span class="n">extra</span><span class="p">,</span>
        <span class="p">})</span>

    <span class="k">def</span> <span class="nf">trace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a TRACE request.&quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;TRACE&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">options</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
                <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="s2">&quot;Construct an OPTIONS request.&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;OPTIONS&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">,</span>
                            <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">put</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
            <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a PUT request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;PUT&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">,</span>
                            <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">patch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
              <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a PATCH request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;PATCH&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">,</span>
                            <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
               <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct a DELETE request.&quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span><span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">,</span>
                            <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">generic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
                <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Construct an arbitrary HTTP request.&quot;&quot;&quot;</span>
        <span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>  <span class="c1"># path can be lazy</span>
        <span class="n">data</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>
        <span class="n">r</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s1">&#39;PATH_INFO&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_path</span><span class="p">(</span><span class="n">parsed</span><span class="p">),</span>
            <span class="s1">&#39;REQUEST_METHOD&#39;</span><span class="p">:</span> <span class="n">method</span><span class="p">,</span>
            <span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">:</span> <span class="s1">&#39;443&#39;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s1">&#39;80&#39;</span><span class="p">,</span>
            <span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">:</span> <span class="s1">&#39;https&#39;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s1">&#39;http&#39;</span><span class="p">,</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="n">data</span><span class="p">:</span>
            <span class="n">r</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
                <span class="s1">&#39;CONTENT_LENGTH&#39;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)),</span>
                <span class="s1">&#39;CONTENT_TYPE&#39;</span><span class="p">:</span> <span class="n">content_type</span><span class="p">,</span>
                <span class="s1">&#39;wsgi.input&#39;</span><span class="p">:</span> <span class="n">FakePayload</span><span class="p">(</span><span class="n">data</span><span class="p">),</span>
            <span class="p">})</span>
        <span class="n">r</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">extra</span><span class="p">)</span>
        <span class="c1"># If QUERY_STRING is absent or empty, we want to extract it from the URL.</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">):</span>
            <span class="c1"># WSGI requires latin-1 encoded strings. See get_path_info().</span>
            <span class="n">query_string</span> <span class="o">=</span> <span class="n">parsed</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;iso-8859-1&#39;</span><span class="p">)</span>
            <span class="n">r</span><span class="p">[</span><span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">query_string</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="o">**</span><span class="n">r</span><span class="p">)</span></div>


<div class="viewcode-block" id="Client"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client">[docs]</a><span class="k">class</span> <span class="nc">Client</span><span class="p">(</span><span class="n">RequestFactory</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A class that can act as a client for testing purposes.</span>

<span class="sd">    It allows the user to compose GET and POST requests, and</span>
<span class="sd">    obtain the response that the server gave to those requests.</span>
<span class="sd">    The server Response objects are annotated with the details</span>
<span class="sd">    of the contexts and templates that were rendered during the</span>
<span class="sd">    process of serving the request.</span>

<span class="sd">    Client objects are stateful - they will retain cookie (and</span>
<span class="sd">    thus session) details for the lifetime of the Client instance.</span>

<span class="sd">    This is not intended as a replacement for Twill/Selenium or</span>
<span class="sd">    the like - it is here to allow testing against the</span>
<span class="sd">    contexts and templates produced by a view, rather than the</span>
<span class="sd">    HTML rendered to the end-user.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">defaults</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">defaults</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">handler</span> <span class="o">=</span> <span class="n">ClientHandler</span><span class="p">(</span><span class="n">enforce_csrf_checks</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">def</span> <span class="nf">store_exc_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Store exceptions when they are generated by a view.&quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Return the current session variables.&quot;&quot;&quot;</span>
        <span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
        <span class="n">cookie</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">cookie</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">(</span><span class="n">cookie</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>

        <span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
        <span class="n">session</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">]</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">session_key</span>
        <span class="k">return</span> <span class="n">session</span>

    <span class="k">def</span> <span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        The master request method. Compose the environment dictionary and pass</span>
<span class="sd">        to the handler, return the result of the handler. Assume defaults for</span>
<span class="sd">        the query environment, which can be overridden using the arguments to</span>
<span class="sd">        the request.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">environ</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_base_environ</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">)</span>

        <span class="c1"># Curry a data dictionary into an instance of the template renderer</span>
        <span class="c1"># callback function.</span>
        <span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="n">on_template_render</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">store_rendered_templates</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
        <span class="n">signal_uid</span> <span class="o">=</span> <span class="s2">&quot;template-render-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
        <span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">on_template_render</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
        <span class="c1"># Capture exceptions created by the handler.</span>
        <span class="n">exception_uid</span> <span class="o">=</span> <span class="s2">&quot;request-exception-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
        <span class="n">got_request_exception</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store_exc_info</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">TemplateDoesNotExist</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
                <span class="c1"># If the view raises an exception, Django will attempt to show</span>
                <span class="c1"># the 500.html template. If that template is not available,</span>
                <span class="c1"># we should ignore the error in favor of re-raising the</span>
                <span class="c1"># underlying exception that caused the 500 error. Any other</span>
                <span class="c1"># template found to be missing during view error handling</span>
                <span class="c1"># should be reported as-is.</span>
                <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span> <span class="o">!=</span> <span class="p">(</span><span class="s1">&#39;500.html&#39;</span><span class="p">,):</span>
                    <span class="k">raise</span>

            <span class="c1"># Look for a signalled exception, clear the current context</span>
            <span class="c1"># exception data, then re-raise the signalled exception.</span>
            <span class="c1"># Also make sure that the signalled exception is cleared from</span>
            <span class="c1"># the local cache!</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span><span class="p">:</span>
                <span class="n">_</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span>
                <span class="k">raise</span> <span class="n">exc_value</span>

            <span class="c1"># Save the client and request that stimulated the response.</span>
            <span class="n">response</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="bp">self</span>
            <span class="n">response</span><span class="o">.</span><span class="n">request</span> <span class="o">=</span> <span class="n">request</span>

            <span class="c1"># Add any rendered template detail to the response.</span>
            <span class="n">response</span><span class="o">.</span><span class="n">templates</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;templates&quot;</span><span class="p">,</span> <span class="p">[])</span>
            <span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;context&quot;</span><span class="p">)</span>

            <span class="n">response</span><span class="o">.</span><span class="n">json</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parse_json</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

            <span class="c1"># Attach the ResolverMatch instance to the response</span>
            <span class="n">response</span><span class="o">.</span><span class="n">resolver_match</span> <span class="o">=</span> <span class="n">SimpleLazyObject</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">resolve</span><span class="p">(</span><span class="n">request</span><span class="p">[</span><span class="s1">&#39;PATH_INFO&#39;</span><span class="p">]))</span>

            <span class="c1"># Flatten a single context. Not really necessary anymore thanks to</span>
            <span class="c1"># the __getattr__ flattening in ContextList, but has some edge-case</span>
            <span class="c1"># backwards-compatibility implications.</span>
            <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
                <span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

            <span class="c1"># Update persistent cookie data.</span>
            <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">)</span>

            <span class="k">return</span> <span class="n">response</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
            <span class="n">got_request_exception</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>

<div class="viewcode-block" id="Client.get"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.get">[docs]</a>    <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Request a response from the server using GET.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.post"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.post">[docs]</a>    <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">MULTIPART_CONTENT</span><span class="p">,</span>
             <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Request a response from the server using POST.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.head"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.head">[docs]</a>    <span class="k">def</span> <span class="nf">head</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Request a response from the server using HEAD.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.options"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.options">[docs]</a>    <span class="k">def</span> <span class="nf">options</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
                <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Request a response from the server using OPTIONS.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">options</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.put"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.put">[docs]</a>    <span class="k">def</span> <span class="nf">put</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
            <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Send a resource to the server using PUT.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.patch"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.patch">[docs]</a>    <span class="k">def</span> <span class="nf">patch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
              <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Send a resource to the server using PATCH.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">patch</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.delete"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.delete">[docs]</a>    <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;application/octet-stream&#39;</span><span class="p">,</span>
               <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Send a DELETE request to the server.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.trace"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.trace">[docs]</a>    <span class="k">def</span> <span class="nf">trace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Send a TRACE request to the server.&quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">trace</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

<div class="viewcode-block" id="Client.login"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.login">[docs]</a>    <span class="k">def</span> <span class="nf">login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">credentials</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the Factory to appear as if it has successfully logged into a site.</span>

<span class="sd">        Return True if login is possible; False if the provided credentials</span>
<span class="sd">        are incorrect.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="kn">from</span> <span class="nn">django.contrib.auth</span> <span class="k">import</span> <span class="n">authenticate</span>
        <span class="n">user</span> <span class="o">=</span> <span class="n">authenticate</span><span class="p">(</span><span class="o">**</span><span class="n">credentials</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_login</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
            <span class="k">return</span> <span class="kc">True</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span></div>

<div class="viewcode-block" id="Client.force_login"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.force_login">[docs]</a>    <span class="k">def</span> <span class="nf">force_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">get_backend</span><span class="p">():</span>
            <span class="kn">from</span> <span class="nn">django.contrib.auth</span> <span class="k">import</span> <span class="n">load_backend</span>
            <span class="k">for</span> <span class="n">backend_path</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">AUTHENTICATION_BACKENDS</span><span class="p">:</span>
                <span class="n">backend</span> <span class="o">=</span> <span class="n">load_backend</span><span class="p">(</span><span class="n">backend_path</span><span class="p">)</span>
                <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="s1">&#39;get_user&#39;</span><span class="p">):</span>
                    <span class="k">return</span> <span class="n">backend_path</span>
        <span class="k">if</span> <span class="n">backend</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">backend</span> <span class="o">=</span> <span class="n">get_backend</span><span class="p">()</span>
        <span class="n">user</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="n">backend</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_login</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span></div>

    <span class="k">def</span> <span class="nf">_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="kn">from</span> <span class="nn">django.contrib.auth</span> <span class="k">import</span> <span class="n">login</span>
        <span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>

        <span class="c1"># Create a fake request to store login details.</span>
        <span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
            <span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
        <span class="n">login</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span>

        <span class="c1"># Save the session values.</span>
        <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>

        <span class="c1"># Set the cookie to represent the session.</span>
        <span class="n">session_cookie</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">session_cookie</span><span class="p">]</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">session_key</span>
        <span class="n">cookie_data</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s1">&#39;max-age&#39;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
            <span class="s1">&#39;path&#39;</span><span class="p">:</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span>
            <span class="s1">&#39;domain&#39;</span><span class="p">:</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_DOMAIN</span><span class="p">,</span>
            <span class="s1">&#39;secure&#39;</span><span class="p">:</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_SECURE</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
            <span class="s1">&#39;expires&#39;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
        <span class="p">}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">session_cookie</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cookie_data</span><span class="p">)</span>

<div class="viewcode-block" id="Client.logout"><a class="viewcode-back" href="../../../topics/testing/tools.html#django.test.Client.logout">[docs]</a>    <span class="k">def</span> <span class="nf">logout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Log out the user by removing the cookies and session object.&quot;&quot;&quot;</span>
        <span class="kn">from</span> <span class="nn">django.contrib.auth</span> <span class="k">import</span> <span class="n">get_user</span><span class="p">,</span> <span class="n">logout</span>

        <span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>
        <span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
            <span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
            <span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">get_user</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
        <span class="n">logout</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span></div>

    <span class="k">def</span> <span class="nf">_parse_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s1">&#39;_json&#39;</span><span class="p">):</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">JSON_CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">)):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                    <span class="s1">&#39;Content-Type header is &quot;</span><span class="si">{0}</span><span class="s1">&quot;, not &quot;application/json&quot;&#39;</span>
                    <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">))</span>
                <span class="p">)</span>
            <span class="n">response</span><span class="o">.</span><span class="n">_json</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">content</span><span class="o">.</span><span class="n">decode</span><span class="p">(),</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">_json</span>

    <span class="k">def</span> <span class="nf">_handle_redirects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Follow any redirects by requesting responses from the server using GET.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">redirect_status_codes</span> <span class="o">=</span> <span class="p">(</span>
            <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">MOVED_PERMANENTLY</span><span class="p">,</span>
            <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">FOUND</span><span class="p">,</span>
            <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">SEE_OTHER</span><span class="p">,</span>
            <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">TEMPORARY_REDIRECT</span><span class="p">,</span>
            <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">PERMANENT_REDIRECT</span><span class="p">,</span>
        <span class="p">)</span>
        <span class="k">while</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="n">redirect_status_codes</span><span class="p">:</span>
            <span class="n">response_url</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">url</span>
            <span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span>
            <span class="n">redirect_chain</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">response_url</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">))</span>

            <span class="n">url</span> <span class="o">=</span> <span class="n">urlsplit</span><span class="p">(</span><span class="n">response_url</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span><span class="p">:</span>
                <span class="n">extra</span><span class="p">[</span><span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span>
            <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">hostname</span><span class="p">:</span>
                <span class="n">extra</span><span class="p">[</span><span class="s1">&#39;SERVER_NAME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">hostname</span>
            <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">port</span><span class="p">:</span>
                <span class="n">extra</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>

            <span class="c1"># Prepend the request path to handle relative path redirects</span>
            <span class="n">path</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">path</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">):</span>
                <span class="n">path</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s1">&#39;PATH_INFO&#39;</span><span class="p">],</span> <span class="n">path</span><span class="p">)</span>

            <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span><span class="n">HTTPStatus</span><span class="o">.</span><span class="n">TEMPORARY_REDIRECT</span><span class="p">,</span> <span class="n">HTTPStatus</span><span class="o">.</span><span class="n">PERMANENT_REDIRECT</span><span class="p">):</span>
                <span class="c1"># Preserve request method post-redirect for 307/308 responses.</span>
                <span class="n">request_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s1">&#39;REQUEST_METHOD&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">request_method</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span>
                <span class="n">data</span> <span class="o">=</span> <span class="n">QueryDict</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">query</span><span class="p">)</span>
                <span class="n">content_type</span> <span class="o">=</span> <span class="kc">None</span>

            <span class="n">response</span> <span class="o">=</span> <span class="n">request_method</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span> <span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">)</span>
            <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">redirect_chain</span>

            <span class="k">if</span> <span class="n">redirect_chain</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="n">redirect_chain</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
                <span class="c1"># Check that we&#39;re not redirecting to somewhere we&#39;ve already</span>
                <span class="c1"># been to, to prevent loops.</span>
                <span class="k">raise</span> <span class="n">RedirectCycleError</span><span class="p">(</span><span class="s2">&quot;Redirect loop detected.&quot;</span><span class="p">,</span> <span class="n">last_response</span><span class="o">=</span><span class="n">response</span><span class="p">)</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">redirect_chain</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">20</span><span class="p">:</span>
                <span class="c1"># Such a lengthy chain likely also means a loop, but one with</span>
                <span class="c1"># a growing path, changing view, or changing query argument;</span>
                <span class="c1"># 20 is the value of &quot;network.http.redirection-limit&quot; from Firefox.</span>
                <span class="k">raise</span> <span class="n">RedirectCycleError</span><span class="p">(</span><span class="s2">&quot;Too many redirects.&quot;</span><span class="p">,</span> <span class="n">last_response</span><span class="o">=</span><span class="n">response</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">response</span></div>
</pre></div>

          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Mar 04, 2020</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>